package com.ezhan.install;

import com.ezhan.api.Service.MysqlServiceImpl;
import com.ezhan.entity.PackageInfo;
import com.ezhan.utils.EnvUtils;
import com.ezhan.utils.PathUtils;

import java.io.*;

import static com.ezhan.logging.LogManager.log;
import static com.ezhan.message.NotifierManager.showError;
import static com.ezhan.message.NotifierManager.showSuccess;
import static com.ezhan.utils.EnvUtils.isAlreadyInPath;
import static com.ezhan.utils.PathUtils.replacePathPlaceholder;


public class PackageInstaller {
    private static final String JDK_NAME = "jdk-17.0.10_windows-x64_bin.exe";
    private static final String PYTHON_NAME = "python-3.8.10-amd64.exe";
    private static final String MYSQL_NAME = "mysql-8.0.37-winx64.zip";

    EnvUtils envUtils = new EnvUtils();

    public boolean installPackage(PackageInfo packageInfo, String installPath, File parentDir) {
        log("开始安装: " + packageInfo.fileName);

        File InstallPath = new File(parentDir, packageInfo.fileName);  //File拼接
        log("使用本地安装包: " + InstallPath.getAbsolutePath());
        log("安装路径: " + installPath);

        // 替换路径占位符
        String[] installArgs = (new PathUtils()).replacePathPlaceholders(packageInfo.installArgs, installPath);
        String installPathToVerify = replacePathPlaceholder(packageInfo.installPath, installPath);

        //数据库下载方式zip
        if (packageInfo.fileName.contains("mysql-8.0.37-winx64")) {
            return (new MysqlServiceImpl()).installMySQLFromZip(packageInfo, installPath, parentDir);
        }

        //其他软件安装
        try {
            // 2. 执行安装命令
            log("正在执行安装命令...");
            String[] command = createInstallCommand(InstallPath, installArgs);

            ProcessBuilder builder = new ProcessBuilder(command);
            builder.redirectErrorStream(true);
            Process process = builder.start();

            try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
                String line;
                while ((line = reader.readLine()) != null) {
                    log(line); // 实时输出安装日志
                }
            }

            int exitCode = process.waitFor();
            if (exitCode != 0) {
                log("错误: 安装失败，退出代码: " + exitCode);
                return false;
            }

            // 3. 验证安装
            log("验证安装结果...");
            File installCheck = new File(installPathToVerify);
            if (!installCheck.exists()) {
                log("警告: 安装验证失败 - 文件不存在 " + installCheck.getAbsolutePath());
                return false;
            } else {
                log("安装成功: " + packageInfo.fileName);
                //安装成功，设置系统变量
                setEnv(packageInfo,installPath);
                return true;
            }
        } catch (Exception e) {
            log("安装过程中发生错误: " + e.getMessage());
            StringWriter sw = new StringWriter();
            e.printStackTrace(new PrintWriter(sw));
            log(sw.toString());
            return false;
        }
    }

    //安装指令
    private String[] createInstallCommand(File file, String[] installArgs) {
        String fileName = file.getName().toLowerCase();

        if (fileName.endsWith(".exe")) {
            String[] cmd = new String[installArgs.length + 1];
            cmd[0] = file.getAbsolutePath();
            System.arraycopy(installArgs, 0, cmd, 1, installArgs.length);
            return cmd;
        } else if (fileName.endsWith(".msi")) {
            String[] cmd = new String[installArgs.length + 3];
            cmd[0] = "msiexec";
            cmd[1] = "/i";
            cmd[2] = file.getAbsolutePath();
            System.arraycopy(installArgs, 0, cmd, 3, installArgs.length);
            return cmd;
        }
        return new String[]{file.getAbsolutePath()};
    }

    //设置系统变量
    public void setEnv(PackageInfo packageInfo, String installPath) {
        //开始设置系统变量
        log("设置系统变量.....");
        //判断是否为jdk安装
        if (packageInfo.getFileName().equals(JDK_NAME)) {
            String target_path = installPath + "\\bin";
            //判断目标路径是否存在系统变量
            if (!isAlreadyInPath(target_path)) {
                log("开始设置jdk的系统变量==>" + target_path);
                if (envUtils.addToPathWithSafetyCheck(target_path)) {
                    showSuccess("jdk设置系统变量成功");
                } else {
                    showError("jdk设置系统变量失败");
                }
            } else {
                log("目标路径在系统变量中存在.....");
            }
        }
        //判断是否为python安装
        else if (packageInfo.getFileName().equals(PYTHON_NAME)) {
            String target_FirstPath = installPath + "\\Scripts";
            String target_SecondPath = installPath;
            //判断目标路径是否存在系统变量
            if (!isAlreadyInPath(target_FirstPath) && !isAlreadyInPath(target_SecondPath)) {
                log("开始设置python的系统变量==>" + target_FirstPath + target_SecondPath);
                if (envUtils.addToPathWithSafetyCheck(target_FirstPath) && envUtils.addToPathWithSafetyCheck(target_SecondPath)) {
                    showSuccess("python设置系统变量成功");
                } else {
                    showError("python设置系统变量失败");
                }
            } else {
                log("目标路径在系统变量中存在.....");
            }
        }
        //判断是否为mysql安装
        else if (packageInfo.getFileName().equals(MYSQL_NAME)) {
            String target_path = installPath + "\\mysql-8.0.37-winx64\\bin";
            //判断目标路径是否存在系统变量
            if (!isAlreadyInPath(target_path)) {
                log("开始设置MySQL的系统变量==>" +target_path);
                if (envUtils.addToPathWithSafetyCheck(target_path)) {
                    showSuccess("MySQL设置系统变量成功");
                } else {
                    showError("MySQL设置系统变量失败");
                }
            } else {
                log("目标路径在系统变量中存在.....");
            }
        }else {
            showSuccess("无需设置系统变量.....");
        }
    }
}
